﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Project.T4Code
{
    /// <summary>
    /// 这个是T4模版使用的类
    /// 所需要的Model和Common程序集必须引用到当前这个类库中
    /// </summary>
    public class T4ManagerCode
    {
        /// <summary>
        /// 获取程序集中的类
        /// </summary>
        /// <returns></returns>
        public Type[] GetAssemblyTypes()
        {
            //string path = ModelPath;
            //byte[] bytes = File.ReadAllBytes(path);
            //Assembly assembly = Assembly.Load(bytes);

            //load方法里可以直接写程序集名字
            //反射出Model中所有的类
            Assembly modelAssembly = Assembly.Load("Project.Model");

            return modelAssembly.GetTypes();
        }

        /// <summary>
        /// 获取类中的属性
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public PropertyInfo[] GetTypeProperties(Type t)
        {
            return t.GetProperties();
        }

        /// <summary>
        /// 获取相应的数据类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public string GetPropertyType(string type)
        {
            switch (type.ToLower())
            {
                case "int16":
                    return "short";
                case "int32":
                    return "int";
                case "int64":
                    return "long";
                case "string":
                    return "string";
                case "boolean":
                    return "bool";
                case "dateTime":
                    return "DateTime";
                case "decimal":
                    return "decimal";
                case "double":
                    return "double";
                case "guid":
                    return "Guid";
                case "object":
                    return "object";
                case "enum":
                    return "short";
                default:
                    return "string";
            }
        }

        /// <summary>
        /// 获取连接器类型
        /// </summary>
        /// <returns></returns>
        public string GetProvider()
        {
            //想用配置文件配置 不过出现问题，待解决
            //return ConfigurationManager.ConnectionStrings["ConnectionString"].ProviderName;
            return "System.Data.OracleClient";
        }

        #region Old
        ///// <summary>
        ///// 获取insert语句
        ///// </summary>
        ///// <param name="tableName">表名/Model类名</param>
        ///// <param name="properties">列名/属性名</param>
        ///// <returns>插入sql语句</returns>
        //public string GetInsertSql(string tableName, PropertyInfo[] properties)
        //{
        //    StringBuilder sb = new StringBuilder();
        //    for (int i = 0, j = properties.Length; i < j; i++)
        //    {
        //        var attribute = properties[i].GetCustomAttributes(typeof(DataObjectFieldAttribute)).FirstOrDefault() as DataObjectFieldAttribute;
        //        //有属性标签
        //        if (attribute != null)
        //        {
        //            //直接调用方法将参数生成出来放到sb中
        //            sb.Append(GetStringFirst(1, properties[i].Name, tableName, i, j, tableDict.Keys.Contains(properties[i].Name), attribute.PrimaryKey));
        //        }
        //        else//没有标签
        //        {
        //            sb.Append(GetStringFirst(1, properties[i].Name, tableName, i, j, tableDict.Keys.Contains(properties[i].Name)));
        //        }


        //        #region Old
        //        //if (!attribute.PrimaryKey)
        //        //{
        //        //    if (i == properties.Length - 1)
        //        //    {
        //        //        //判断是否有关联的类
        //        //        if (tableDict.Keys.Contains(properties[i].Name))
        //        //        {
        //        //            sb.Append("@" + properties[i].Name + "Id");
        //        //        }
        //        //        else
        //        //        {
        //        //            sb.Append("@" + properties[i].Name);
        //        //        }
        //        //    }
        //        //    else
        //        //    {
        //        //        //判断是否有关联的类
        //        //        if (tableDict.Keys.Contains(properties[i].Name))
        //        //        {
        //        //            sb.Append("@" + properties[i].Name + "Id" + ",");
        //        //        }
        //        //        else
        //        //        {
        //        //            sb.Append("@" + properties[i].Name + ",");
        //        //        }
        //        //    }
        //        //} 
        //        #endregion
        //    }
        //    return string.Format("insert into {0}({1}) values({2});SELECT CAST(SCOPE_IDENTITY() as int)", tableName, sb.ToString().Replace("@", ""), sb.ToString());

        //}

        ///// <summary>
        ///// 修改Sql语句
        ///// </summary>
        ///// <param name="tableName">表名/Model类名</param>
        ///// <param name="properties">列名/属性名</param>
        ///// <returns>更新Sql语句</returns>
        //public string GetUpdateSql(string tableName, PropertyInfo[] properties)
        //{
        //    StringBuilder sb = new StringBuilder();
        //    StringBuilder keySb = new StringBuilder();
        //    for (int i = 0, j = properties.Length; i < j; i++)
        //    {
        //        var attribute = properties[i].GetCustomAttributes(typeof(DataObjectFieldAttribute)).FirstOrDefault() as DataObjectFieldAttribute;
        //        //有标签
        //        if (attribute != null)
        //        {
        //            //主键要放到单独的sb中
        //            if (attribute.PrimaryKey)
        //            {
        //                keySb.Append(GetStringFirst(2, properties[i].Name, tableName, i, j, tableDict.Keys.Contains(properties[i].Name), attribute.PrimaryKey));
        //            }
        //            else
        //            {
        //                sb.Append(GetStringFirst(2, properties[i].Name, tableName, i, j, tableDict.Keys.Contains(properties[i].Name), attribute.PrimaryKey));
        //            }

        //        }
        //        else//没有标签
        //        {
        //            sb.Append(GetStringFirst(2, properties[i].Name, tableName, i, j, tableDict.Keys.Contains(properties[i].Name)));
        //        }


        //        #region Old
        //        //修改的时候主键作为条件，不需要判断是否为最后一个参数
        //        //主键肯定不会是关联外键，不需要判断是否关联
        //        //if (attribute.PrimaryKey)
        //        //{
        //        //    keySb.Append(string.Format("{0} = @{0}", properties[i].Name));
        //        //}
        //        //else
        //        //{
        //        //    if (i == properties.Length - 1)
        //        //    {
        //        //        //判断是否有关联的类
        //        //        if (tableDict.Keys.Contains(properties[i].Name))
        //        //        {
        //        //            sb.Append(string.Format("{0} = @{0}", properties[i].Name + "Id"));
        //        //        }
        //        //        else
        //        //        {
        //        //            sb.Append(string.Format("{0} = @{0}", properties[i].Name));
        //        //        }
        //        //    }
        //        //    else
        //        //    {
        //        //        //判断是否有关联的类
        //        //        if (tableDict.Keys.Contains(properties[i].Name))
        //        //        {
        //        //            sb.Append(string.Format("{0} = @{0},", properties[i].Name + "Id"));
        //        //        }
        //        //        else
        //        //        {
        //        //            sb.Append(string.Format("{0} = @{0},", properties[i].Name));
        //        //        }
        //        //    }
        //        //} 
        //        #endregion


        //    }

        //    return string.Format("update {0} set {1} where {2}", tableName, sb.ToString(), keySb.ToString());
        //}

        ///// <summary>
        ///// 获取删除语句
        ///// </summary>
        ///// <param name="tableName">表名/Model类名/</param>
        ///// <param name="properties">列名/属性名</param>
        ///// <returns>删除sql语句</returns>
        //public string GetDeleteSql(string tableName, PropertyInfo[] properties)
        //{
        //    StringBuilder sb = new StringBuilder();
        //    int j = 0;
        //    for (int i = 0; i < properties.Length; i++)
        //    {
        //        var attribute = properties[i].GetCustomAttributes(typeof(DataObjectFieldAttribute)).FirstOrDefault() as DataObjectFieldAttribute;
        //        //删除的时候只需要主键
        //        if (attribute.PrimaryKey)
        //        {
        //            sb.Append(string.Format("{0} = @{0}", properties[i].Name));
        //            break;
        //        }
        //        else
        //        {
        //            j++;
        //        }
        //    }
        //    if (j == properties.Length)
        //    {
        //        throw new Exception("表必须有主键!");
        //    }
        //    return string.Format("delete {0} where {1} ", tableName, sb.ToString());
        //}
        ///// <summary>
        ///// 获取查询语句
        ///// </summary>
        ///// <param name="tableName">表名/Model类名</param>
        ///// <param name="properties">列名/属性名</param>
        ///// <returns>查询sql语句</returns>
        //public string GetLoadSql(string tableName, PropertyInfo[] properties)
        //{
        //    //拼接sql语句
        //    StringBuilder baseSb = new StringBuilder();
        //    //保存包含类 key为包含类的类名 value为包含类的主键
        //    Dictionary<string, string> contentDict = new Dictionary<string, string>();
        //    //保存包含类名及属性字符串
        //    Dictionary<string, StringBuilder> contentSbDict = new Dictionary<string, StringBuilder>();
        //    for (int i = 0, j = properties.Length; i < j; i++)
        //    {
        //        //有包含类的时候将包含类也关联查询出来
        //        if (tableDict.Keys.Contains(properties[i].Name))
        //        {
        //            //属性字符串
        //            StringBuilder contentSb = new StringBuilder();
        //            var contentProperties = GetTypeProperties(tableDict[properties[i].Name]);
        //            //遍历包含类属性
        //            for (int m = 0, n = contentProperties.Length; m < n; m++)
        //            {
        //                //获取属性的标签
        //                var attribute = contentProperties[m].GetCustomAttributes(typeof(DataObjectFieldAttribute)).FirstOrDefault() as DataObjectFieldAttribute;
        //                //判断主键
        //                if (attribute != null && attribute.PrimaryKey)
        //                {
        //                    //将包含类名和主键放到字典中
        //                    contentDict.Add(properties[i].Name, contentProperties[m].Name);
        //                }
        //                contentSb.Append(GetStringFirst(4, contentProperties[m].Name, properties[i].Name, m, n,
        //                                                tableDict.Keys.Contains(contentProperties[m].Name), false,
        //                                                enumList.Contains(contentProperties[m].Name)));
        //            }
        //            contentSbDict.Add(properties[i].Name, contentSb);
        //        }
        //        else
        //        {
        //            //主类属性字符串放到相应的集合中
        //            baseSb.Append(GetStringFirst(4, properties[i].Name, tableName, i, j, tableDict.Keys.Contains(properties[i].Name), false, enumList.Contains(properties[i].Name)));
        //        }


        //        #region Old
        //        //if (i == properties.Length - 1)
        //        //{
        //        //    //如果是枚举，查询的时候需要做些操作
        //        //    if (enumList.Contains(properties[i].Name))
        //        //    {
        //        //        sb.Append(string.Format("CAST({0} as int) as {0}", properties[i].Name));
        //        //    }
        //        //    else
        //        //    {
        //        //        sb.Append(properties[i].Name);
        //        //    }
        //        //}
        //        //else
        //        //{
        //        //    if (enumList.Contains(properties[i].Name))
        //        //    {
        //        //        sb.Append(string.Format("CAST({0} as int) as {0},", properties[i].Name));
        //        //    }
        //        //    else
        //        //    {
        //        //        sb.Append(properties[i].Name + ",");
        //        //    }
        //        //} 
        //        #endregion
        //    }
        //    //查询语句例子，采用left join
        //    //select u.Id,u.UserName,u.Age,CAST(u.Gender as int) Gender,u.Address,u.CreateTime,u.Phone,u.EmployeeId,e.Id,e.LoginName,e.LoginPwd from UserInfo u left join Employee e on u.EmployeeId=e.Id

        //    StringBuilder sb = new StringBuilder();
        //    //主类的第一个字母
        //    string tableLowerFirst = tableName.ToLower().Substring(0, 1);
        //    string baseStr = baseSb.ToString();
        //    if (baseStr.LastIndexOf(',') == baseStr.Length - 1)
        //    {
        //        baseStr = baseStr.Substring(0, baseStr.Length - 1);
        //    }
        //    sb.Append(string.Format("select {0} ", baseStr));
        //    //遍历包含类的属性字符串，放到sql语句中
        //    foreach (var contentTableName in contentSbDict.Keys)
        //    {
        //        sb.Append(string.Format(",{0}", contentSbDict[contentTableName]));
        //    }
        //    sb.Append(string.Format(" from {0} {1}", tableName, tableLowerFirst));
        //    //遍历包含类的主键 拼接join语句
        //    foreach (var contentTableName in contentDict.Keys)
        //    {
        //        //包含类的第一个字母
        //        string contentTableNameLowerFirst = contentTableName.ToLower().Substring(0, 1);
        //        sb.Append(string.Format(" left join {0} {1} on {2}.{3} = {4}.{5} ", contentTableName, contentTableNameLowerFirst, tableLowerFirst, contentTableName + "Id", contentTableNameLowerFirst, contentDict[contentTableName]));
        //    }

        //    return sb.ToString();
        //}
        ///// <summary>
        ///// 第一次获取字符串
        ///// </summary>
        ///// <param name="status">1代表insert，2，代表update，3代表delete，4代表select</param>
        ///// <param name="propertyName">属性参数</param>
        ///// <param name="tableName">表名，查询的时候需要用到</param>
        ///// <param name="nowLength">循环到的第几个参数</param>
        ///// <param name="length">总的参数个数</param>
        ///// <param name="isKey">是否为主键，默认不是主键</param>
        ///// <param name="isContent">是否含有包含类</param>
        ///// <returns></returns>
        //public string GetStringFirst(int status, string propertyName, string tableName, int nowLength, int length, bool isContent = false, bool isKey = false, bool isEnum = false)
        //{
        //    string result = "";
        //    switch (status)
        //    {
        //        //insert
        //        case 1:
        //            //insert时 主键不需要当作参数传进来
        //            if (!isKey)
        //            {
        //                if (nowLength == length - 1)
        //                {
        //                    result = GetStringSecond("@{0}", propertyName, isContent);
        //                }
        //                else
        //                {
        //                    result = GetStringSecond("@{0}", propertyName, isContent) + ",";
        //                }
        //            }
        //            break;
        //        //update
        //        case 2:
        //            //update时 主键作为条件
        //            if (!isKey)
        //            {
        //                if (nowLength == length - 1)
        //                {
        //                    result = GetStringSecond("{0} = @{0}", propertyName, isContent);
        //                }
        //                else
        //                {
        //                    result = GetStringSecond("{0} = @{0}", propertyName, isContent) + ",";
        //                }
        //            }
        //            else
        //            {
        //                result = GetStringSecond("{0} = @{0}", propertyName, isContent);
        //            }
        //            break;
        //        //delete
        //        case 3:
        //            //删除时只需要将主键传过去
        //            if (isKey)
        //            {
        //                result = GetStringSecond("{0} = @{0}", propertyName, isContent);
        //            }
        //            break;
        //        //select
        //        case 4:
        //            //列名，当是枚举列的时候需要特殊处理
        //            string pName = tableName.Substring(0, 1).ToLower() + "." + propertyName;
        //            //查询的时候需要把所有的都查询出来，所有的都放到参数里面，不需要判断主键
        //            if (nowLength == length - 1)
        //            {
        //                if (isEnum)
        //                {
        //                    result = GetEnumString("CAST({0} as int) as {1}", pName, propertyName);
        //                }
        //                else
        //                {
        //                    if (!isContent)
        //                    {
        //                        result = GetStringSecond("{0}", pName);
        //                    }

        //                }
        //            }
        //            else
        //            {
        //                if (isEnum)
        //                {
        //                    result = GetEnumString("CAST({0} as int) as {1},", pName, propertyName);
        //                }
        //                else
        //                {
        //                    if (!isContent)
        //                    {
        //                        result = GetStringSecond("{0}", pName) + ",";
        //                    }
        //                }
        //            }
        //            break;
        //        default: result = ""; break;
        //    }
        //    return result;
        //}
        ///// <summary>
        ///// 第二次获取字符串
        ///// </summary>
        ///// <param name="model">字符串模版</param>
        ///// <param name="propertyName">参数</param>
        ///// <param name="isContent">是否包含类</param>
        ///// <returns></returns>
        //public string GetStringSecond(string model, string propertyName, bool isContent = false)
        //{
        //    string result = "";
        //    //判断是否有包含类，有包含类将参数名后面加上Id
        //    if (isContent)
        //    {
        //        result = string.Format(model, propertyName + "Id");
        //    }
        //    else
        //    {
        //        result = string.Format(model, propertyName);
        //    }
        //    return result;
        //}
        ///// <summary>
        ///// 获取枚举字符串
        ///// </summary>
        ///// <param name="model">字符串模版</param>
        ///// <param name="propertyName1">第一个参数</param>
        ///// <param name="propertyName2">第二个参数</param>
        ///// <returns></returns>
        //public string GetEnumString(string model, string propertyName1, string propertyName2)
        //{
        //    return string.Format(model, propertyName1, propertyName2);
        //} 


        ///// <summary>
        ///// 获取相应的所有包含的子类
        ///// </summary>
        ///// <param name="properties"></param>
        ///// <returns></returns>
        //public List<string> GetAllContentTable(PropertyInfo[] properties)
        //{
        //    List<string> contentList = new List<string>();
        //    foreach (var property in properties)
        //    {
        //        if (tableDict.Keys.Contains(property.PropertyType.Name))
        //        {
        //            contentList.Add(property.PropertyType.Name);
        //        }
        //    }
        //    return contentList;
        //}


        ///// <summary>
        ///// 联查的时候需要特殊处理query条件
        ///// </summary>
        ///// <param name="tableName">表名</param>
        ///// <param name="properties">属性名</param>
        ///// <returns></returns>
        //public string GetConQueryStr(string tableName, PropertyInfo[] properties)
        //{
        //    string result = "";
        //    string tableLowerFirst = tableName.ToLower().Substring(0, 1);
        //    var contentList = GetAllContentTable(properties);
        //    if (contentList.Count > 0)
        //    {
        //        StringBuilder sb = new StringBuilder();
        //        StringBuilder sb1 = new StringBuilder();
        //        StringBuilder sb2 = new StringBuilder();
        //        StringBuilder sb3 = new StringBuilder();
        //        sb1.Append(tableName + ", ");
        //        sb2.Append(tableLowerFirst + ", ");
        //        for (int i = 0; i < contentList.Count; i++)
        //        {
        //            //var userList = connection.Query<UserInfo, Employee, UserInfo>(sql, (u, e) => { u.Employee = e; return u; });
        //            string contentLowerFirst = contentList[i].ToLower().Substring(0, 1);
        //            sb1.Append(contentList[i] + ", ");
        //            sb2.Append(contentLowerFirst);
        //            sb3.Append(string.Format("{0}.{1} = {2};", tableLowerFirst, contentList[i], contentLowerFirst));
        //        }
        //        sb1.Append(tableName);
        //        sb3.Append(string.Format("return {0};", tableLowerFirst));

        //        result = string.Format("connection.Query<{0}>(sql, ({1}) => {{{2}}})",sb1,sb2,sb3);
        //    }
        //    else
        //    {
        //        result = string.Format("connection.Query<{0}>(sql)", tableName);
        //    }
        //    return result;
        //}


        #endregion

    }
}